home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 07 - 1991 / 07.03 Mar 91 / PICS Code / PICS Unit Source < prev    next >
Encoding:
Text File  |  1990-12-05  |  7.0 KB  |  254 lines  |  [TEXT/AOqc]

  1. {}
  2. {    PICS Unit    -    Steve Sheets}
  3. {}
  4. {    This Unit provides the Interface to the PICS data structure}
  5. {    as well as the procedures to create, dispose and draw the}
  6. {    PICS information.}
  7.  
  8. unit PICSUnit;
  9.  
  10. interface
  11.  
  12.     const
  13.         kPICStype = 'PICS';        {File type of PICS}
  14.         kINFOtype = 'INFO';        {Resource type of PICS information resource}
  15.  
  16. {    Interface for the optional information handle and the PICS handle}
  17. {    which contains 1 or more Pictures and the information handle.}
  18. {    Notice that the PICS handle is a variable length handle based on}
  19. {    the number of frames.}
  20.  
  21.     type
  22.         TPICSInfoRec = record
  23.                 BWColor: INTEGER;        {0 = Black & White, 1 = Color}
  24.                 Depth: INTEGER;            {1,2,4,8,16 pixel depth}
  25.                 Speed: INTEGER;            {1..200 frames per sec, else negative seconds per frame}
  26.                 Version: INTEGER;        {0 currently}
  27.                 Creator: ResType;        {original creator signature}
  28.                 Largest: LongInt;            {if non-zero, largest picture size}
  29.             end;
  30.         TPICSInfoPtr = ^TPICSInfoRec;
  31.         TPICSInfoHdl = ^TPICSInfoPtr;
  32.  
  33.         TPICSRec = record
  34.                 NumFrames, DimH, DimV: INTEGER;
  35.                 PICSInfoHdl: TPICSInfoHdl;
  36.                 Frame: array[1..1] of PicHandle;
  37.             end;
  38.         TPICSPtr = ^TPICSRec;
  39.         TPICSHdl = ^TPICSPtr;
  40.  
  41.  
  42. {    Given a file name and volume reference number,  try to read the PICS}
  43. {    file at that location.  If successful, return noErr in the function and }
  44. {    the information in thePICS parameter.  If there was a problem, return}
  45. {    the error number in the function, and thePICS is set to NIL.}
  46.  
  47.     function ReadPICS (theFileName: Str255;
  48.                                     theVRefNum: INTEGER;
  49.                                     var thePICS: TPICSHdl): OSErr;
  50.  
  51. {    Given thePICS data, dispos of all the handles and data structures.}
  52.  
  53.     procedure DisposePICS (thePICS: TPICSHdl);
  54.  
  55. {    Given thePICS data, and an V & H position to draw at, draw the}
  56. {    animation.  The Loopflag tells the procedure to either loop the}
  57. {    animation continously (TRUE), or only draw once time (FALSE).}
  58. {    The ScanKeyFlag tells the procedure if it should look to see if}
  59. {    someone has pressed a key during animation.  If so, the procedure}
  60. {    is stopped at that point.  Notice that it is dangerous to have }
  61. {    Loopflag set TRUE and ScanKeyFlag set FALSE (infinite loop time).}
  62.  
  63.     procedure DrawPICS (thePICS: TPICSHdl;
  64.                                     HPos, VPos: INTEGER;
  65.                                     LoopFlag, ScanKeyFlag: BOOLEAN);
  66.  
  67. implementation
  68.  
  69. {    Simple utility function, given number of frames, size of the TPICSRec}
  70. {    record in bytes.}
  71.  
  72.     function PICSsize (theNumFrames: INTEGER): INTEGER;
  73.     begin
  74.         PICSsize := (theNumFrames * 4) + 10;
  75.     end;
  76.  
  77.     function ReadPICS (theFileName: Str255;
  78.                                     theVRefNum: INTEGER;
  79.                                     var thePICS: TPICSHdl): OSErr;
  80.         var
  81.             tempE: OSErr;
  82.             tempResNum: INTEGER;
  83.             tempSize: INTEGER;
  84.             tempPICS: TPICSHdl;
  85.             tempPicture: PicHandle;
  86.             tempFlag: BOOLEAN;
  87.     begin
  88.         thePICS := nil;
  89.         tempPICS := nil;
  90.         tempPicture := nil;
  91.  
  92.         tempResNum := OpenRFPerm(theFileName, theVRefNum, 0);
  93.         if tempResNum = -1 then
  94.             tempE := ResError
  95.         else
  96.             begin
  97.                 tempPicture := PicHandle(Get1Resource('PICT', 128));
  98.                 if tempPicture = nil then
  99.                     tempE := ResError
  100.                 else
  101.                     begin
  102.                         HNoPurge(Handle(tempPicture));
  103.                         DetachResource(Handle(tempPicture));
  104.  
  105.                         tempSize := 100;
  106.                         tempPICS := TPICSHdl(NewHandle(PICSsize(tempSize)));
  107.                         if tempPICS = nil then
  108.                             tempE := MemError
  109.                         else
  110.                             begin
  111.                                 with tempPICS^^ do
  112.                                     begin
  113.                                         NumFrames := 1;
  114.                                         with tempPicture^^.picFrame do
  115.                                             begin
  116.                                                 DimH := Right - Left;
  117.                                                 DimV := Bottom - Top;
  118.                                             end;
  119.                                         PICSInfoHdl := nil;
  120.                                         Frame[1] := tempPicture;
  121.                                     end;
  122.                                 tempPicture := nil;
  123.  
  124.                                 tempPICS^^.PICSInfoHdl := TPICSInfoHdl(Get1Resource(kINFOtype, 128));
  125.                                 if tempPICS^^.PICSInfoHdl <> nil then
  126.                                     begin
  127.                                         HNoPurge(Handle(tempPICS^^.PICSInfoHdl));
  128.                                         DetachResource(Handle(tempPICS^^.PICSInfoHdl));
  129.                                     end;
  130.  
  131.                                 tempFlag := FALSE;
  132.                                 repeat
  133.                                     tempPicture := PicHandle(Get1Resource('PICT', 128 + tempPICS^^.NumFrames));
  134.                                     if tempPicture = nil then
  135.                                         begin
  136.                                             tempE := ResError;
  137.                                             if (tempE = resNotFound) or (tempE = noErr) then
  138.                                                 begin
  139.                                                     tempE := noErr;
  140.                                                     SetHandleSize(Handle(tempPICS), PICSsize(tempPICS^^.NumFrames));
  141.                                                     thePICS := tempPICS;
  142.                                                     tempPICS := nil;
  143.                                                 end;
  144.                                             tempFlag := TRUE;
  145.                                         end
  146.                                     else
  147.                                         begin
  148.                                             HNoPurge(Handle(tempPicture));
  149.                                             DetachResource(Handle(tempPicture));
  150.                                             if tempPICS^^.NumFrames = tempSize then
  151.                                                 begin
  152.                                                     tempSize := tempSize + 100;
  153.                                                     SetHandleSize(Handle(tempPICS), PICSsize(tempSize));
  154.                                                     tempE := ResError;
  155.                                                 end;
  156.                                             if tempE = noErr then
  157.                                                 begin
  158.                                                     tempPICS^^.NumFrames := tempPICS^^.NumFrames + 1;
  159.                                                     tempPICS^^.Frame[tempPICS^^.NumFrames] := tempPicture;
  160.                                                     tempPicture := nil;
  161.                                                 end
  162.                                             else
  163.                                                 tempFlag := TRUE;
  164.                                         end;
  165.                                 until tempFlag;
  166.                             end;
  167.  
  168.                     end;
  169.                 CloseResFile(tempResNum);
  170.             end;
  171.  
  172.         if tempPICS <> nil then
  173.             DisposePICS(tempPICS);
  174.         if tempPicture <> nil then
  175.             DisposHandle(Handle(tempPicture));
  176.  
  177.         ReadPICS := tempE;
  178.     end;
  179.  
  180.     procedure DisposePICS (thePICS: TPICSHdl);
  181.         var
  182.             tempNum: INTEGER;
  183.     begin
  184.         if thePICS <> nil then
  185.             begin
  186.                 if thePICS^^.PICSInfoHdl <> nil then
  187.                     DisposHandle(Handle(thePICS^^.PICSInfoHdl));
  188.                 for tempNum := 1 to thePICS^^.NumFrames do
  189.                     DisposHandle(Handle(thePICS^^.Frame[tempNum]));
  190.                 DisposHandle(Handle(thePICS));
  191.             end;
  192.     end;
  193.  
  194.     procedure DrawPICS (thePICS: TPICSHdl;
  195.                                     HPos, VPos: INTEGER;
  196.                                     LoopFlag, ScanKeyFlag: BOOLEAN);
  197.         var
  198.             tempRect: Rect;
  199.             tempTicks: LongInt;
  200.             tempDone: BOOLEAN;
  201.             tempCount: INTEGER;
  202.  
  203. {    Wait tempTicks number of ticks, stopping at any time if mouse or key is pressed.}
  204.  
  205.         procedure WaitFrame;
  206.             var
  207.                 tempLong: LongInt;
  208.                 tempEvent: EventRecord;
  209.         begin
  210.             tempLong := tickCount + tempTicks;
  211.             while (tempLong > tickCount) and (not tempDone) do
  212.                 begin
  213.                     SystemTask;
  214.                     tempDone := GetNextEvent(mDownMask + keyDownMask + autoKeyMask, tempEvent);
  215.                 end;
  216.         end;
  217.  
  218.     begin
  219.         if thePICS <> nil then
  220.             if thePICS^^.NumFrames > 0 then
  221.                 if thePICS^^.Frame[1] <> nil then
  222.                     begin
  223.                         tempDone := FALSE;
  224.                         if thePICS^^.PICSInfoHdl <> nil then
  225.                             begin
  226.                                 tempTicks := thePICS^^.PICSInfoHdl^^.Speed;
  227.                                 if tempTicks <= 0 then
  228.                                     tempTicks := -60 * tempTicks
  229.                                 else
  230.                                     tempTicks := 60 div tempTicks;
  231.                             end
  232.                         else
  233.                             tempTicks := 6;
  234.  
  235.                         repeat
  236.                             tempCount := 0;
  237.                             repeat
  238.                                 tempCount := tempCount + 1;
  239.  
  240.                                 if thePICS^^.Frame[tempCount] <> nil then
  241.                                     if not EmptyRect(thePICS^^.Frame[tempCount]^^.PicFrame) then
  242.                                         begin
  243.                                             tempRect := thePICS^^.Frame[tempCount]^^.PicFrame;
  244.                                             OffSetRect(tempRect, HPos, VPos);
  245.                                             DrawPicture(thePICS^^.Frame[tempCount], tempRect);
  246.                                         end;
  247.                                 WaitFrame;
  248.  
  249.                             until tempDone or (tempCount >= thePICS^^.NumFrames);
  250.                         until tempDone or (not LoopFlag);
  251.                     end;
  252.     end;
  253.  
  254. end.